#include "app_mqtt.h"

#define ADDRESS "ws://192.168.55.42:1883"              // MQTT服务器地址
#define CLIENTID "b253ba38-daf6-4b37-984f-5d8fdc6a1cf5" // 客户端ID
#define TOPIC_PULL "zrc_pull"                                // 客户端订阅的主题
#define TOPIC_PUSH "zrc_push"                                // 发布主题
#define QOS 1                                           // QOS等级
#define TIMEOUT 10000L                                  // 超时时间

static receCallback recev_callback = NULL;

static MQTTClient client;

static MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;

static MQTTClient_message pubmsg = MQTTClient_message_initializer; // 需要发布的消息

// 消息到达回调函数
static void delivered(void *context, MQTTClient_deliveryToken dt)
{
    log_debug("发送消息完成");
}

// 链接断开回调函数
static void connlost(void *context, char *cause)
{
    log_error("链接断开，原因：%s", cause);
}

/**
 * @brief 接收到远程发送过来的消息的回调函数
 * @param context 上下文
 * @param topicName 主题名称
 * @param topicLen 主题长度
 * @param message 消息
 * @note  此函数比较特别(与一般函数相反)：返回1代表接收处理函数成功了，返回0代表接收处理函数失败了
 */
static int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
    int result = 0;
    if (recev_callback != NULL)
    {
        // 将消息的有效负载（payload）和长度传递给接收处理函数
        log_debug("收到数据：%.*s",message->payloadlen,message->payload);
        result = recev_callback(message->payload, message->payloadlen) == 0 ? 1 : 0;
    }
    // 释放消息和主题名称
    MQTTClient_freeMessage(&message);
    MQTTClient_free(topicName);
    return result;
}

int app_mqtt_init(void)
{
    int result;
    // 创建MQTT客户端
    if ((result = MQTTClient_create(&client, ADDRESS, CLIENTID,
                                    MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS)
    {
        log_error("MQTTClient_create failed");
        return -1;
    }
    // 设置回调函数
    if ((result = MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered)) != MQTTCLIENT_SUCCESS)
    {
        log_error("Failed to set callbacks");
        MQTTClient_destroy(&client);
        return -1;
    }
    // 链接MQTT服务器
    if ((result = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
    {
        log_error("Failed to connect");
        MQTTClient_destroy(&client);
        return -1;
    }
    // 订阅主题
    if ((result = MQTTClient_subscribe(client, TOPIC_PULL, QOS)) != MQTTCLIENT_SUCCESS)
    {
        printf("Failed to subscribe");
        MQTTClient_disconnect(client, TIMEOUT);
        MQTTClient_destroy(&client);
        return -1;
    }
    return 0;
}

int app_mqtt_send(char *data, int len)
{

    // 设置消息的有效负载（payload）为传入的数据
    pubmsg.payload = data;

    // 设置消息的有效负载长度（payload length）为传入的长度
    pubmsg.payloadlen = len;

    // 设置消息的服务质量（QoS）级别
    pubmsg.qos = QOS;

    int result = 0;
    // 尝试发布消息
    if ((result = MQTTClient_publishMessage(client, TOPIC_PUSH, &pubmsg, NULL)) != MQTTCLIENT_SUCCESS)
    {
        // 如果发布消息失败，记录错误日志
        log_error("Failed to publish message");
        return -1;
    }
    // 如果发布消息成功，返回0
    return 0;
}

void app_mqtt_close(void)
{
    // 取消订阅主题
    MQTTClient_unsubscribe(client, TOPIC_PULL);
    // 断开链接
    MQTTClient_disconnect(client, TIMEOUT);
    // 销毁客户端
    MQTTClient_destroy(&client);
}

void app_mqtt_resigterRecvCallBack(receCallback callback)
{
    recev_callback = callback;
}